package com.itheima.filter;

import com.alibaba.fastjson.JSON;
import com.itheima.common.BaseContext;
import com.itheima.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author Gareth Cao
 * @date 2022/4/26 9:31
 */
@WebFilter("/*") //这里的路径是过滤器过滤所有请求
@Slf4j
public class CheckLoginFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //将请求和响应强转,这样才能使用getsession方法
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        // 禁止远程访问
       /* String remoteAddr = request.getRemoteAddr();
        System.out.println(remoteAddr);
        if (!remoteAddr.equals("0:0:0:0:0:0:0:1")) {
            return;
        }*/

        //获取请求的路径
        String requestURI = request.getRequestURI();
        //对所有的静态资源不应该过滤,直接放行,只需要拦截 登录到html里面之后发送的异步请求就行,因为就算进入了html页面但页面发送异步请求之后的路径还是被过滤
        //定义该放行的路径
        String[] uris = {"/backend/**",
                "/front/**",
                "/employee/login",
                //发送验证码的路径不应该拦截
                "/user/sendMsg",
                //登录(即注册)路径也不应该拦截
                "/user/login",
                "/doc.html",
                "/webjars/**",
                "/swagger-resources",
                "/v2/api-docs"
        };
        boolean flag = checkUri(uris, requestURI);
        if (flag) {
            //匹配,直接放行
            filterChain.doFilter(request, response);
            //不再需要下面的代码了,直接结束方法
            return;
        }

        //获取session中的数据
        Long empId = (Long) request.getSession().getAttribute("empId");
        if (empId != null) {
            //这里表示已经登录成功了
            //打印当前线程的id
            log.info("当前线程的id: {}", Thread.currentThread().getId());
            //调用BaseContext中静态方法设置数据
            BaseContext.setCurrentId(empId);
            //session中存在对象id,即已经登录,放行
            filterChain.doFilter(request, response);
            return;
        }

        Long userId = (Long) request.getSession().getAttribute("userId");
        if (userId != null) {
            //这里表示已经登录成功了
            //打印当前线程的id
            log.info("当前线程的id: {}", Thread.currentThread().getId());
            //调用BaseContext中静态方法设置数据
            BaseContext.setCurrentId(userId);
            //session中存在对象id,即已经登录,放行
            filterChain.doFilter(request, response);
            return;
        }
        //如果执行到这一步,session中不存在对象id,即没有登录,根据前端里request.js的要求来写
        R<Object> notLogin = R.error("NOTLOGIN");
        //使用fastjson里的工具类来将结果集对象进行json字符串转换
        String jsonString = JSON.toJSONString(notLogin);
        //前端会获取响应中的json字符串转为对象
        response.getWriter().write(jsonString);
    }

    private boolean checkUri(String[] uris, String requestURI) {
        //对放行的路径进行遍历与请求的路径进行匹配
        for (String uri : uris) {
            AntPathMatcher pathMatcher = new AntPathMatcher();
            boolean match = pathMatcher.match(uri, requestURI);
            if (match) {
                //匹配
                return true;
            }
        }
        //遍历结束都不匹配
        return false;
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }


    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
